package com.education.ai.dao.impl;

import com.education.ai.dao.StudentPracticeSessionDao;
import com.education.ai.entity.StudentPracticeSession;
import com.education.ai.util.JdbcUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 学生练习会话DAO实现类
 */
@Repository
public class StudentPracticeSessionDaoImpl implements StudentPracticeSessionDao {

    private static final Logger logger = LoggerFactory.getLogger(StudentPracticeSessionDaoImpl.class);
    
    @Autowired
    private JdbcUtil jdbcUtil;

    @Override
    public StudentPracticeSession save(StudentPracticeSession session) {
        if (session.getId() == null) {
            // 日志记录所有参数值，用于调试
            logger.debug("保存练习会话，参数: studentId={}, subject={}, topic={}, difficulty={}, practiceType={}, totalCount={}, correctCount={}, startTime={}, endTime={}, accuracy={}",
                session.getStudentId(),
                session.getSubject(),
                session.getKnowledgePoint(),
                session.getDifficulty(),
                session.getPracticeType(),
                session.getTotalCount(),
                session.getCorrectCount(),
                session.getStartTime(),
                session.getEndTime(),
                session.getAccuracy());

            // 插入操作
            String sql = "INSERT INTO student_practice_sessions (student_id, subject, topic, difficulty, " +
                    "practice_type, total_count, correct_count, question_count, start_time, end_time, accuracy) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            // 确保所有参数不为null
            String studentId = session.getStudentId();
            String subject = session.getSubject();
            String topic = session.getKnowledgePoint();
            String difficulty = session.getDifficulty() != null ? session.getDifficulty() : "中等";
            String practiceType = session.getPracticeType() != null ? session.getPracticeType() : "日常练习";
            Integer totalCount = session.getTotalCount() != null ? session.getTotalCount() : 0;
            Integer correctCount = session.getCorrectCount() != null ? session.getCorrectCount() : 0;
            Integer questionCount = totalCount; // question_count默认等于total_count
            LocalDateTime startTime = session.getStartTime() != null ? session.getStartTime() : LocalDateTime.now();
            LocalDateTime endTime = session.getEndTime() != null ? session.getEndTime() : LocalDateTime.now();
            Double accuracy = session.getAccuracy() != null ? session.getAccuracy() : 0.0;

            long id = jdbcUtil.executeInsert(sql, 
                    studentId,
                    subject,
                    topic,
                    difficulty,
                    practiceType,
                    totalCount,
                    correctCount,
                    questionCount,
                    startTime,
                    endTime,
                    accuracy);
            
            session.setId(id);
            return session;
        } else {
            // 更新操作
            String sql = "UPDATE student_practice_sessions SET " +
                    "student_id = ?, subject = ?, topic = ?, difficulty = ?, " +
                    "practice_type = ?, total_count = ?, correct_count = ?, question_count = ?, " +
                    "start_time = ?, end_time = ?, accuracy = ? " +
                    "WHERE id = ?";
            
            jdbcUtil.executeUpdate(sql,
                    session.getStudentId(),
                    session.getSubject(),
                    session.getKnowledgePoint(),
                    session.getDifficulty() != null ? session.getDifficulty() : "中等", // 提供默认值
                    session.getPracticeType() != null ? session.getPracticeType() : "日常练习", // 提供默认值
                    session.getTotalCount(),
                    session.getCorrectCount(),
                    session.getTotalCount(), // question_count默认等于total_count
                    session.getStartTime(),
                    session.getEndTime(),
                    session.getAccuracy(),
                    session.getId());
            
            return session;
        }
    }

    @Override
    public StudentPracticeSession findById(Long id) {
        String sql = "SELECT * FROM student_practice_sessions WHERE id = ?";
        List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, id);
        
        if (!results.isEmpty()) {
            return mapRowToSession(results.get(0));
        }
        
        return null;
    }

    @Override
    public List<StudentPracticeSession> findByStudentId(String studentId) {
        String sql = "SELECT * FROM student_practice_sessions WHERE student_id = ? ORDER BY start_time DESC";
        List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, studentId);
        
        return mapResultsToSessions(results);
    }

    @Override
    public List<StudentPracticeSession> findByStudentIdAndSubject(String studentId, String subject) {
        String sql = "SELECT * FROM student_practice_sessions WHERE student_id = ? AND subject = ? ORDER BY start_time DESC";
        List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, studentId, subject);
        
        return mapResultsToSessions(results);
    }

    @Override
    public List<StudentPracticeSession> findRecentByStudentId(String studentId, int limit) {
        String sql = "SELECT * FROM student_practice_sessions WHERE student_id = ? ORDER BY start_time DESC LIMIT ?";
        List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, studentId, limit);
        
        return mapResultsToSessions(results);
    }

    @Override
    public void deleteById(Long id) {
        String sql = "DELETE FROM student_practice_sessions WHERE id = ?";
        jdbcUtil.executeUpdate(sql, id);
    }

    @Override
    public List<StudentPracticeSession> saveAll(List<StudentPracticeSession> sessions) {
        List<StudentPracticeSession> savedSessions = new ArrayList<>();
        for (StudentPracticeSession session : sessions) {
            savedSessions.add(save(session));
        }
        return savedSessions;
    }
    
    /**
     * 将查询结果映射为练习会话对象列表
     */
    private List<StudentPracticeSession> mapResultsToSessions(List<Map<String, Object>> results) {
        List<StudentPracticeSession> sessions = new ArrayList<>();
        for (Map<String, Object> row : results) {
            sessions.add(mapRowToSession(row));
        }
        return sessions;
    }
    
    /**
     * 将单行结果映射为练习会话对象
     */
    private StudentPracticeSession mapRowToSession(Map<String, Object> row) {
        StudentPracticeSession session = new StudentPracticeSession();
        
        session.setId(((Number) row.get("id")).longValue());
        session.setStudentId((String) row.get("student_id"));
        session.setSubject((String) row.get("subject"));
        session.setKnowledgePoint((String) row.get("topic"));
        session.setDifficulty((String) row.get("difficulty"));
        session.setPracticeType((String) row.get("practice_type"));
        
        Object totalCountObj = row.get("total_count");
        if (totalCountObj != null) {
            session.setTotalCount(((Number) totalCountObj).intValue());
        }
        
        Object correctCountObj = row.get("correct_count");
        if (correctCountObj != null) {
            session.setCorrectCount(((Number) correctCountObj).intValue());
        }
        
        // 处理日期时间字段
        if (row.get("start_time") != null) {
            Object timeObj = row.get("start_time");
            if (timeObj instanceof Timestamp) {
                session.setStartTime(((Timestamp) timeObj).toLocalDateTime());
            } else if (timeObj instanceof LocalDateTime) {
                session.setStartTime((LocalDateTime) timeObj);
            }
        }
        
        if (row.get("end_time") != null) {
            Object timeObj = row.get("end_time");
            if (timeObj instanceof Timestamp) {
                session.setEndTime(((Timestamp) timeObj).toLocalDateTime());
            } else if (timeObj instanceof LocalDateTime) {
                session.setEndTime((LocalDateTime) timeObj);
            }
        }
        
        Object accuracyObj = row.get("accuracy");
        if (accuracyObj != null) {
            session.setAccuracy(((Number) accuracyObj).doubleValue());
        }
        
        return session;
    }
}